#pragma once

#include "mod.h"

namespace sfc::num {

template <class T>
constexpr auto is_unsigned() -> bool {
  return T(-1) > 0;
}

template <class T>
constexpr auto is_signed() -> bool {
  return T(-1) < 0;
}

template <class T>
constexpr auto abs(T val) -> T {
  return val < 0 ? -val : val;
}

template <class T>
auto align_up(T value, T align) -> T {
  return (value + T(align) - 1) / T(align) * T(align);
}

template <class T>
auto align_down(T value, usize align) -> T {
  return value / T(align) * T(align);
}

template <class T>
auto up_to_pow2(T min_value) -> T {
  auto res = T(1);
  while (res < min_value) {
    res *= 2;
  }
  return res;
}

template <class T>
auto checked_sub(T lhs, T rhs) -> T {
  return lhs > rhs ? lhs - rhs : 0;
}

}  // namespace sfc::num
